package main

import (
	"encoding/json"
	"log"
	"net/http"

	_ "github.com/go-sql-driver/mysql"
)

// SQLRequest 执行SQL的请求结构
type SQLRequest struct {
	SQL        string        `json:"sql"`
	Args       []interface{} `json:"args"`
	RequestID  string        `json:"requestId,omitempty"`
	Operation  string        `json:"operation"`
	DBType     string        `json:"db_type"`    // 数据库类型: mysql 或 bigquery
	Connection string        `json:"connection"` // 连接名称
}

// SQLResponse 执行SQL的响应结构
type SQLResponse struct {
	Columns []string        `json:"columns,omitempty"`
	Rows    [][]interface{} `json:"rows,omitempty"`
	Error   string          `json:"error,omitempty"`
}

// Config 服务器配置信息
type Config struct {
	// MySQL配置
	MySQLEnabled     bool              `json:"mysql_enabled"`     // 是否启用MySQL
	MySQLConnections map[string]string `json:"mysql_connections"` // MySQL连接配置 name -> dsn

	// BigQuery配置
	BigQueryEnabled     bool                          `json:"bigquery_enabled"`     // 是否启用BigQuery
	BigQueryConnections map[string]BigQueryConnection `json:"bigquery_connections"` // BigQuery连接配置

	// Redis配置
	RedisProxyEnabled bool             `json:"redis_proxy_enabled"` // 是否启用Redis代理
	RedisProxyConfig  RedisProxyConfig `json:"redis_proxy_config"`  // Redis代理配置

	// HTTP服务配置
	HTTPAddr string `json:"http_addr"` // HTTP服务地址
}

// Server 服务器实例
type Server struct {
	config         Config
	mysqlServer    *MySQLServer
	bigqueryServer *BigQueryServer
	redisServer    *RedisServer
}

// NewServer 创建新的服务器实例
func NewServer(config Config) (*Server, error) {
	server := &Server{
		config: config,
	}

	// 初始化MySQL服务器
	if config.MySQLEnabled {
		mysqlServer, err := NewMySQLServer(config.MySQLConnections)
		if err != nil {
			return nil, err
		}
		server.mysqlServer = mysqlServer
	}

	// 初始化BigQuery服务器
	if config.BigQueryEnabled {
		bigqueryServer, err := NewBigQueryServer(config.BigQueryConnections)
		if err != nil {
			return nil, err
		}
		server.bigqueryServer = bigqueryServer
	}

	// 初始化Redis代理服务器
	if config.RedisProxyEnabled {
		redisServer, err := NewRedisServer(config.RedisProxyConfig)
		if err != nil {
			return nil, err
		}
		server.redisServer = redisServer
	}

	return server, nil
}

// HandleSQL 处理SQL执行请求
func (s *Server) HandleSQL(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "仅支持POST请求", http.StatusMethodNotAllowed)
		return
	}

	var req SQLRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, err.Error(), http.StatusBadRequest)
		return
	}

	var resp SQLResponse

	// 根据数据库类型处理请求
	switch req.DBType {
	case "mysql":
		if s.mysqlServer != nil {
			resp = s.mysqlServer.HandleRequest(req)
		} else {
			resp.Error = "MySQL未启用"
		}
	case "bigquery":
		if s.bigqueryServer != nil {
			resp = s.bigqueryServer.HandleRequest(req)
		} else {
			resp.Error = "BigQuery未启用"
		}
	default:
		resp.Error = "未知的数据库类型: " + req.DBType
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(resp)
}

// StartServices 启动所有服务
func (s *Server) StartServices() error {
	// 启动Redis代理
	if s.redisServer != nil {
		if err := s.redisServer.Start(); err != nil {
			return err
		}
	}

	return nil
}

func main() {
	// 默认配置
	config := Config{
		MySQLEnabled: true,
		MySQLConnections: map[string]string{
			"default": "root:root@tcp(127.0.0.1:3306)/test",
		},
		BigQueryEnabled: false,
		BigQueryConnections: map[string]BigQueryConnection{
			"default": {
				Project:         "your-project-id",
				Dataset:         "your_dataset",
				CredentialsFile: "credentials.json",
			},
		},
		RedisProxyEnabled: true,
		RedisProxyConfig: RedisProxyConfig{
			LocalAddr:  ":6380",          // 本地监听端口
			RemoteAddr: "127.0.0.1:6379", // Redis真实地址
		},
		HTTPAddr: ":8080",
	}

	server, err := NewServer(config)
	if err != nil {
		log.Fatalf("无法创建服务器: %v", err)
	}

	// 启动服务
	if err := server.StartServices(); err != nil {
		log.Fatalf("启动服务失败: %v", err)
	}

	http.HandleFunc("/sql", server.HandleSQL)
	log.Printf("数据库代理服务器在 %s 启动", config.HTTPAddr)
	log.Fatal(http.ListenAndServe(config.HTTPAddr, nil))
}
